#include "StdAfx.h"
#include "App.h"
#include "AppWindow.h"
#include "Enviroment.h"
#include "CaelumEnv.h"
#include "UIEnv.h"
#include "OISEnv.h"
#include <OgreOverlayManager.h>

using namespace Ogre;
#define BACKGROUND "vwdbg.jpg"
#define LOADING "loading.png"
#define LOADING_IMGWIDTH 200
#define LOADING_IMGHEIGHT 63

void SetupResourcesDir( const char* resourceFileName )
{
	FILE* fp = fopen( resourceFileName, "rb" );
    if( fp != 0 )
        fclose( fp );
	else
	{
		std::string msg = "Can`t open ";
		msg += resourceFileName;
		Ogre::LogManager::getSingleton().logMessage( msg.c_str() );
		return;
	}
	
	std::string msg = "Loading ";
	msg += resourceFileName;
	Ogre::LogManager::getSingleton().logMessage( msg.c_str() );
    Ogre::ConfigFile cf;
	cf.load(resourceFileName);
    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();

	Ogre::String secName, typeName, archName;
    while (seci.hasMoreElements())
    {
        secName = seci.peekNextKey();
        Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
        Ogre::ConfigFile::SettingsMultiMap::iterator i;
        for (i = settings->begin(); i != settings->end(); ++i)
        {
            typeName = i->first;
            archName = i->second;

            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName);
        }		
    }

	Ogre::LogManager::getSingleton().logMessage( "Resource directories setup" );
}

void UIEnv_OnRequestShutdown()
{
	VWD::AppWindow::getInstancePtr()->StopRendering();
}

Ogre::MaterialPtr CreateSimpleTextureMaterial(const char* textureName)
{
	MaterialPtr material = MaterialManager::getSingleton().create(textureName, "General");
	material->getTechnique(0)->getPass(0)->createTextureUnitState(textureName);
	material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
	material->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
	material->getTechnique(0)->getPass(0)->setLightingEnabled(false);
	material->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
	
	return material;
}

void CreateBackground()
{
	using namespace Ogre;

	CreateSimpleTextureMaterial(BACKGROUND);

	// Create background rectangle covering the whole screen
	Rectangle2D* rect = new Rectangle2D(true);
	rect->setCorners(-1.0, 1.0, 1.0, -1.0);
	rect->setMaterial(BACKGROUND);

	// Render the background before everything else
	rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND);

	// Use infinite AAB to always stay visible
	AxisAlignedBox aabInf;
	aabInf.setInfinite();
	rect->setBoundingBox(aabInf);

	// Attach background to the scene
	SceneNode* node = VWD::Enviroment::SceneManager->getRootSceneNode()->createChildSceneNode("Background");
	node->attachObject(rect);
}

void CreateLoadingImage()
{
	using namespace Ogre;
	CreateSimpleTextureMaterial(LOADING);

	OverlayManager& om = OverlayManager::getSingleton();

	OverlayContainer* panel = static_cast<OverlayContainer*>(om.createOverlayElement("Panel", "loading"));
	panel->setMetricsMode(Ogre::GMM_PIXELS);	
	panel->setDimensions(LOADING_IMGWIDTH,LOADING_IMGHEIGHT);
	panel->setPosition(-LOADING_IMGWIDTH-10,-LOADING_IMGHEIGHT-10);
	panel->setHorizontalAlignment(GHA_RIGHT);
	panel->setVerticalAlignment(GVA_BOTTOM);
	panel->setMaterialName(LOADING);

	Overlay *ovl = om.create(LOADING);
	ovl->add2D(panel);
	ovl->show();	
}

void DestoryLoadingImage()
{
	OverlayManager::getSingleton().destroy(LOADING);
}

void CreateEnvs()
{	
	Root * proot = Root::getSingletonPtr();
		
	VWD::Enviroment::SceneManager = proot->createSceneManager(ST_EXTERIOR_CLOSE,GENERIC_SCENEMANAGER_NAME);
	
	VWD::Enviroment::Camera = VWD::Enviroment::SceneManager->createCamera(GENERIC_CAMERA_NAME);
	
	VWD::Enviroment::Viewport = VWD::Enviroment::RenderWindow->addViewport(VWD::Enviroment::Camera);
	
	Ogre::SceneNode* cameraNode = VWD::Enviroment::SceneManager->getRootSceneNode()->createChildSceneNode("Camera");
	cameraNode->attachObject(VWD::Enviroment::Camera);
	cameraNode->setPosition(750,200,750);

// 	VWD::Enviroment::SceneManager->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));
// 	VWD::Enviroment::SceneManager->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED);
//	VWD::Enviroment::SceneManager->setWorldGeometry("terrain.cfg");	
	
	VWD::Enviroment::Camera->setNearClipDistance(1);
	VWD::Enviroment::Camera->setFarClipDistance(100000);

	CreateLoadingImage();

	proot->renderOneFrame();	

	//VWD::CaelumEnv::getInstancePtr()->Init();
	VWD::UIEnv::getInstancePtr()->Init();
	VWD::OISEnv::getInstancePtr()->Init();	
	CreateBackground();

	DestoryLoadingImage();

	VWD::UIEnv::getInstancePtr()->OnRequestShutdown.connect(&UIEnv_OnRequestShutdown);
}

void ClearEnvs()
{	
	//VWD::OISEnv::getInstancePtr()->Shutdown();
	//VWD::UIEnv::getInstancePtr()->Shutdown();
	//VWD::CaelumEnv::getInstancePtr()->Shutdown();	
}

VWD::App::App(void)
{	

}

VWD::App::~App(void)
{

}

void VWD::App::Go()
{
	size_t hWnd = AppWindow::getInstanceRef().CreateAppWindow();

	if(hWnd==0)return;

	RenderWindow* pwindow = Enviroment::RenderWindow;

	pwindow->setDeactivateOnFocusChange(false);
	
	Ogre::Root& root = Ogre::Root::getSingleton();

	SetupResourcesDir(GENERIC_RESOURCE_FILENAME);

	Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

	CreateEnvs();

	Ogre::LogManager::getSingletonPtr()->logMessage("App start");

	AppWindow::getInstanceRef().StartRendering();	

	Ogre::LogManager::getSingletonPtr()->logMessage("App stop");

	ClearEnvs();
}

void VWD::App::Config()
{
	Ogre::Root root;
	root.showConfigDialog();
	root.saveConfig();
}